package com.core.managers;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.core.protocols.IAuthenticationDelegate;
import com.core.protocols.IServiceLayerDelegate;
import com.core.utils.GlobalConstants;
import com.entities.user.servicelayer.UserListLayer;
import com.model.user.User;

public class LoginManager
        implements IAuthenticationDelegate, IServiceLayerDelegate {

	private static LoginManager Instance                 = null;
	private boolean             isValidUser              = false;
	private boolean             isLoginFormDisplaying    = false;
	private int                 loginAttemptsCount       = 0;
	private int                 loginFormOpenedInstances = 0;
	private boolean             isLoginGetMethodExecuted = false;
	private int                 userId                   = -1;



	public boolean isLoginGetMethodExecuted () {

		return isLoginGetMethodExecuted;
	}



	public void setLoginGetMethodExecuted ( boolean isLoginGetMethodExecuted ) {

		this.isLoginGetMethodExecuted = isLoginGetMethodExecuted;
	}



	public boolean hasClosedAllLoginForms () {

		return (loginFormOpenedInstances < 1);
	}



	public void incrementLoginformOpenAttepts () {

		loginFormOpenedInstances++;
	}



	public void decrementLoginformOpenAttepts () {

		loginFormOpenedInstances--;
	}



	public void resetLoginformOpenAttepts () {

		loginFormOpenedInstances = 0;
	}



	public int getLoginAttemptsCount () {

		return loginAttemptsCount;
	}



	public void setLoginAttemptsCount ( int loginAttemptsCount ) {

		this.loginAttemptsCount = loginAttemptsCount;
	}



	public boolean isValidUser () {

		return isValidUser;
	}



	public void setValidUser ( boolean isValidUser ) {

		this.isValidUser = isValidUser;
		if ( !isValidUser ) {

		}
	}



	public boolean isLoginFormDisplaying () {

		return isLoginFormDisplaying;
	}



	public void setLoginFormDisplaying ( boolean isLoginFormDisplaying ) {

		this.isLoginFormDisplaying = isLoginFormDisplaying;
	}



	public int getUserId () {

		return userId;
	}



	public void setUserId ( int userId ) {

		this.userId = userId;
	}



	public static LoginManager sharedInstance () {

		if ( Instance == null ) {
			Instance = new LoginManager();
		}
		return Instance;
	}



	public static Boolean authorizedUserForRequest ( ServletRequest request ) {

		SessionManager sessionManager = SessionManager.sharedInstance();
		String sessionIsAuthorizedString = (String) sessionManager.getAttributeValue(GlobalConstants.SM_ATTRIBUTE_IS_AUTHORIZED);
		boolean isAuthorized = "true".equalsIgnoreCase(sessionIsAuthorizedString);

		return isAuthorized;
	}



	public boolean performUserCheck ( String userName,
	                                  String userPassword ) {

		this.isValidUser = false;
		this.userId = -1;

		UserListLayer layer = new UserListLayer();
		layer.setLayerDelegate(this);
		layer.checkValidPassword(userName, userPassword);

		return this.isValidUser;
	}



	@Override
	public boolean isAuthenticated () {

		return true;
	}



	@Override
	public Integer permissions () {

		return 0;
	}



	@Override
	public <T> void responseResponseItemsList ( final List <T> items,
	                                            final Object request,
	                                            final Exception exception ) {

		this.userId = -1;
		this.isValidUser = false;
		if ( items == null ) {
			return;
		}
		this.isValidUser = (items.size() == 1);

		if ( this.isValidUser ) {
			User user = (User) items.get(0);
			this.userId = user.getId();

		}
	}



	public void doDefaultRedirection ( HttpServletRequest request,
	                                   HttpServletResponse response )
	        throws IOException {

		if ( this.isValidUser ) {
			loginAttemptsCount = -1;
			this.isLoginFormDisplaying = false;
			response.sendRedirect(GlobalConstants.SERVLET_DASHBOARD);
		} else {
			this.resetLoginformOpenAttepts();
			loginAttemptsCount++;
			this.isLoginFormDisplaying = true;
			response.sendRedirect(GlobalConstants.SERVLET_LOGIN);
		}

	}
}
